package com.jo.invocation;

import com.jo.interceptor.MethodInterceptor;
import com.jo.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.List;

/**
 * jdk动态代理实现类，
 * proceed（）方法会根据所传递的拦截器链对原始方法进行增强
 * @author Jo
 * @date 2018/1/25
 */
public class ReflectionMethodInvocation implements ProxyMethodInvocation {
    protected Object proxy;
    protected Object target;
    protected Method method;
    protected Object[] args;
    protected List<MethodInterceptor> methodInterceptors;
    private int curInterceptorIndex = -1;


    public ReflectionMethodInvocation(Object proxy, Object target, Method method, Object[] args, List<MethodInterceptor> methodInterceptors) {
        this.proxy = proxy;
        this.target = target;
        this.method = method;
        this.args = args;
        this.methodInterceptors = methodInterceptors;
    }

    @Override
    public Object getProxy() {
        return this.proxy;
    }

    @Override
    public Object proceed() throws Throwable {
        //如果拦截器都执行完了，就直接最原始的方法
        if (this.curInterceptorIndex == this.methodInterceptors.size() - 1){
            return invokeOriginal();
        }

        MethodInterceptor methodInterceptor = this.methodInterceptors.get(++this.curInterceptorIndex);

        return methodInterceptor.invoke(this);
    }


    @Override
    public Method getMethod() {
        return this.method;
    }

    @Override
    public Object[] getArguments() {
        return this.args;
    }

    @Override
    public Object getTarget() {
        return target;
    }

    protected Object invokeOriginal() throws Throwable {
        return ReflectionUtils.methodInvoke(this.method, this.args, this.target);
    }

}
